/**
 * <h3>OpusController</h3>
 * <p>作品信息管理控制器类</p>
 *
 * <h3>功能描述</h3>
 * <p>提供作品信息的增删改查等基础操作接口，统一返回AjaxResult格式结果</p>
 * <p>支持作品的创建、编辑、删除、查询等核心功能，包含分页查询、点赞、浏览统计等</p>
 * <p>所有接口均基于RESTful风格设计，配合SpringMVC与Swagger注解实现标准化API输出</p>
 *
 * <h3>元数据</h3>
 * <ul>
 *    <li>作者：郭强</li>
 *    <li>创建日期：2025年05月06日 21:09:09</li>
 * </ul>
 *
 * <h3>其他信息</h3>
 * <ul>
 *    <li>参考链接：<a href="https://fantastic-admin.hurui.me/guide/permission.html">权限控制文档</a></li>
 *    <li>示例代码：{@code new OpusController(opusService, opusLikeService)} </li>
 * </ul>
 *
 * @apiNote 接口需结合前端权限配置使用，确保安全性；当前部分接口已启用权限注解
 * @implSpec 继承自 {@link BaseController}，复用分页、返回封装等通用逻辑
 * @since 1.0.0
 */

package com.dnndo.web.controller.system;

import com.dnndo.common.annotation.Log;
import com.dnndo.common.core.controller.BaseController;
import com.dnndo.common.core.domain.AjaxResult;
import com.dnndo.common.core.domain.PageResult;
import com.dnndo.common.core.domain.R;
import com.dnndo.common.core.page.TableSupport;
import com.dnndo.common.enums.BusinessType;
import com.dnndo.common.utils.ServletUtils;
import com.dnndo.common.utils.bean.BeanDtoVoUtil;
import com.dnndo.system.domain.Opus;
import com.dnndo.system.domain.dto.*;
import com.dnndo.system.domain.vo.*;
import com.dnndo.system.service.IOpusLikeService;
import com.dnndo.system.service.IOpusService;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.ApiParam;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;

/**
 * 作品信息controller类
 *
 * @author 郭强
 */
@RestController
@RequestMapping("/system/opus")
public class OpusController extends BaseController {

  private final IOpusService opusService;
  private final IOpusLikeService opusLikeService;
  @Autowired
  public OpusController(IOpusService opusService , IOpusLikeService opusLikeService) {
    this.opusService = opusService;
    this.opusLikeService = opusLikeService;
  }

  /**
   * 查询作品列表（分页）
   * @param dto 作品查询条件封装对象，包含名称、用户ID等过滤条件
   * @return PageResult<OpusVO> 分页后的作品信息列表及总记录数
   * @see com.dnndo.system.domain.vo.OpusVO
   */
  @PreAuthorize("@ss.hasPermi('system:opus:list')")
  @GetMapping("/list")
  public PageResult<OpusVO> list(OpusDTO dto) {
    dto.setUserId(getUserId().intValue());
    startPage();
    List<Opus> list = opusService.selectOpusList(dto);
    return PageResult.pageOk(BeanDtoVoUtil.listVo(list, OpusVO.class), new PageInfo<>(list).getTotal());
  }

  /**
   * 查询设计师列表（分页）
   * @param dto 作品查询条件封装对象，包含名称、用户ID等过滤条件
   * @return AjaxResult 分页后的设计师信息列表及总记录数
   * @see com.dnndo.system.domain.dto.OpusDTO
   */
  @PreAuthorize("@ss.hasPermi('system:opus:designerlist')")
  @GetMapping("/designerlist")
  public PageResult<OpusVO> designerlist(OpusDTO dto) {
    startPage();
    dto.setUserId(getUserId().intValue());
    List<OpusDTO> list = opusService.selectdesignerlist(dto);
    return PageResult.pageOk(BeanDtoVoUtil.listVo(list, OpusVO.class), new PageInfo<>(list).getTotal());
  }

  /**
   * 根据作品ID获取详细信息
   * @param opusId 作品唯一标识符
   * @return AjaxResult 包含作品详细信息的响应结果
   * @see com.dnndo.system.domain.vo.OpusVO
   */
  @PreAuthorize("@ss.hasPermi('system:opus:getInfo')")
  @GetMapping("/getInfo")
  public AjaxResult getInfo(@ApiParam(value = "作品ID", required = true) Long opusId) {
    OpusDTO opus = opusService.selectOpusListById(opusId,getUserId());
    return AjaxResult.success(BeanDtoVoUtil.convert(opus, OpusVO.class));
  }

  /**
   * 获取设计师详细信息
   * @param userId 用户唯一标识符
   * @return AjaxResult 包含设计师详细信息的响应结果
   * @see com.dnndo.system.domain.dto.OpusDTO
   */
  @PreAuthorize("@ss.hasPermi('system:opus:designerInfo')")
  @GetMapping("/getdesignerInfo")
  public AjaxResult getdesignerInfo(@ApiParam(value = "用户ID", required = true) Long userId) {
    return AjaxResult.success(opusService.selectdesignerListById(userId));
  }

  /**
   * 新增作品信息
   * @param dto 前端传入的作品数据传输对象，包含新增字段
   * @return AjaxResult 操作结果返回对象，包含成功或失败状态
   * @see com.dnndo.system.domain.dto.OpusDTO
   */
  @PreAuthorize("@ss.hasPermi('system:opus:add')")
  @Log(title = "作品管理", businessType = BusinessType.INSERT)
  @PostMapping("/add")
  public AjaxResult add(@Validated @RequestBody OpusDTO dto) {
    dto.setUserId(getUserId().intValue());
    return toAjax(opusService.insertOpus(dto));
  }

  /**
   * 修改已有作品信息
   * @param dto 前端传入的作品数据传输对象，包含更新字段
   * @return AjaxResult 操作结果返回对象，包含成功或失败状态
   * @see com.dnndo.system.domain.dto.OpusDTO
   */
  @PreAuthorize("@ss.hasPermi('system:opus:getInfo') or @ss.hasPermi('system:opus:status')")
  @Log(title = "作品管理", businessType = BusinessType.UPDATE)
  @PostMapping("/edit")
  public AjaxResult edit(@Validated @RequestBody OpusDTO dto) {
    OpusDTO opusDTO = BeanDtoVoUtil.convert(dto, OpusDTO.class);
    return toAjax(opusService.updateOpusById(opusDTO));
  }

  /**
   * 作品编辑接口（无权限控制）
   * @param dto 前端传入的作品数据传输对象，包含更新字段
   * @return AjaxResult 操作结果返回对象，包含成功或失败状态
   * @see com.dnndo.system.domain.dto.OpusDTO
   */
  @Log(title = "作品管理", businessType = BusinessType.UPDATE)
  @PostMapping("/opusedit")
  public AjaxResult opusedit(@Validated @RequestBody OpusDTO dto) {
    OpusDTO opusDTO = BeanDtoVoUtil.convert(dto, OpusDTO.class);
    return toAjax(opusService.updateOpusById(opusDTO));
  }

  /**
   * 删除指定ID的作品信息
   * @param opusId 要删除的作品唯一标识符
   * @return AjaxResult 操作结果返回对象，包含成功或失败状态
   * @see com.dnndo.system.domain.dto.OpusDTO
   */
  @PreAuthorize("@ss.hasPermi('system:opus:del')")
  @Log(title = "作品管理", businessType = BusinessType.DELETE)
  @GetMapping("/del")
  public AjaxResult del(@ApiParam(value = "作品ID", required = true) Integer opusId) {
    return toAjax(opusService.deleteOpusById(opusId));
  }

  /**
   * 作品删除接口（无权限控制）
   * @param opusId 要删除的作品唯一标识符
   * @return AjaxResult 操作结果返回对象，包含成功或失败状态
   * @see com.dnndo.system.domain.dto.OpusDTO
   */
  @Log(title = "作品删除接口", businessType = BusinessType.DELETE)
  @GetMapping("/delete")
  public AjaxResult delete(@ApiParam(value = "作品ID", required = true) Integer opusId) {
    return toAjax(opusService.deleteOpusById(opusId));
  }

  /**
   * 作品删除接口（无权限控制）
   * @param opusId 要删除的作品唯一标识符
   * @return AjaxResult 操作结果返回对象，包含成功或失败状态
   * @see com.dnndo.system.domain.dto.OpusDTO
   */
  @Log(title = "作品管理", businessType = BusinessType.DELETE)
  @GetMapping("/scdel")
  public AjaxResult scdel(@ApiParam(value = "作品ID", required = true) Integer opusId) {
    return toAjax(opusService.delOpusById(opusId));
  }

  /**
   * 查询校园品牌馆信息
   * @param dto 查询条件封装对象(需包含language字段)
   * @return AjaxResult 包含查询结果的响应对象
   * @see com.dnndo.system.domain.vo.BrandPavilionVO
   * @see com.dnndo.system.domain.vo.BrandPavilionEnVO
   */
  @PostMapping("/campus_brand_pavilion")
  public AjaxResult campusBrandPavilion(@RequestBody BrandPavilionDTO dto) {
    // 将分页参数设置到请求属性中
    HttpServletRequest request = ServletUtils.getRequest();
    request.setAttribute(TableSupport.PAGE_NUM, dto.getPage());
    request.setAttribute(TableSupport.PAGE_SIZE, dto.getSize());

    List<?> listVO;
    int total;

      // 获取总记录数
    startPage();
    if (dto.getLanguage().equals("en")) {
    listVO = BeanDtoVoUtil.listVo(opusService.selectCampusBrandPavilion(dto), BrandPavilionEnVO.class);
    } else {
    listVO = BeanDtoVoUtil.listVo(opusService.selectCampusBrandPavilion(dto), BrandPavilionVO.class);
    }
    total = opusService.countCampusBrandPavilion(dto); // 获取总记录数

      // 使用 HashMap 构建返回数据
    HashMap<String, Object> dataMap = new HashMap<>();
    dataMap.put("total", total);
    dataMap.put("data", listVO);

    return AjaxResult.success(dataMap);
  }

  /**
   * 获取校园大使信息
   * @param dto 包含分页参数和查询条件的校园大使查询对象
   * @return AjaxResult 包含校园大使列表数据和总记录数的响应结果
   * @see com.dnndo.system.domain.vo.AmbassadorVO
   */
  @PostMapping("/ambassador")
  public AjaxResult ambassador(@RequestBody AmbassadorDTO dto) {
    // 将分页参数设置到请求属性中
    HttpServletRequest request = ServletUtils.getRequest();
    request.setAttribute(TableSupport.PAGE_NUM, dto.getPage());
    request.setAttribute(TableSupport.PAGE_SIZE, dto.getSize());

    int total;
    total = opusService.countAmbassador(dto);
    startPage();
    List<AmbassadorVO> list = opusService.getAmbassadorInfo(dto);

    // 使用 HashMap 构建返回数据
    HashMap<String, Object> dataMap = new HashMap<>();
    dataMap.put("total", total);
    dataMap.put("data", list);
    return AjaxResult.success(dataMap);
  }

  /**
   * 获取校园设计师信息
   * @param dto 包含分页参数和查询条件的设计师查询对象
   * @return AjaxResult 包含设计师列表数据和总记录数的响应结果
   * @see com.dnndo.system.domain.vo.DesignerVO
   */
  @PostMapping("/designer")
  public AjaxResult designer(@RequestBody DesignerDTO dto) {
    // 将分页参数设置到请求属性中
    HttpServletRequest request = ServletUtils.getRequest();
    request.setAttribute(TableSupport.PAGE_NUM, dto.getPage());
    request.setAttribute(TableSupport.PAGE_SIZE, dto.getSize());

    int total;
    total = opusService.countDesigner(dto);

    startPage();
    List<DesignerVO> list = opusService.designer(dto);
    // 使用 HashMap 构建返回数据
    HashMap<String, Object> dataMap = new HashMap<>();
    dataMap.put("total", total);
    dataMap.put("data", list);

    return AjaxResult.success(dataMap);
  }

  /**
   * 文创活动-根据作品id，查询相关作品及用户信息
   * @param dto 包含作品ID和语言类型的查询条件
   * @return AjaxResult 包含文创活动相关信息的响应结果
   * @see com.dnndo.system.domain.vo.CulturalVOEN
   * @see com.dnndo.system.domain.vo.CulturalVOZH
   */
  @GetMapping("/cultural")
  public AjaxResult cultural(CulturalDTO dto) {
    Object listVO;
    if (dto.getLanguage().equals("en")) {
      listVO = BeanDtoVoUtil.convert(opusService.cultural(dto), CulturalVOEN.class);
    } else {
      listVO = BeanDtoVoUtil.convert(opusService.cultural(dto), CulturalVOZH.class);
    }
    return AjaxResult.success(listVO);
  }

  /**
   * 根据用户id，查询该用户的所有相关作品
   * @param dto 包含用户ID、分页参数和语言类型的查询条件
   * @return AjaxResult 包含用户作品列表数据和总记录数的响应结果
   * @see com.dnndo.system.domain.vo.OpuslistWithUserInfoVOEN
   * @see com.dnndo.system.domain.vo.OpuslistWithUserInfoVOZH
   */
  @PostMapping("/listWithUserInfo")
  @ResponseBody
  public AjaxResult getWorkListWithUserInfo(@RequestBody OpuslistWithUserInfoDTO dto) {
    try {
      // 将分页参数设置到请求属性中
      HttpServletRequest request = ServletUtils.getRequest();
      request.setAttribute(TableSupport.PAGE_NUM, dto.getPage());
      request.setAttribute(TableSupport.PAGE_SIZE, dto.getSize());

      int total;
      total = opusService.countWorkListWithUserInfo(dto);
      // 设置请求分页数据
      startPage();
      List<?> listVO;

      if (dto.getLanguage().equals("en")) {
        listVO = BeanDtoVoUtil.listVo(opusService.getWorkListWithUserInfo(dto), OpuslistWithUserInfoVOEN.class);
      } else {
        listVO = BeanDtoVoUtil.listVo(opusService.getWorkListWithUserInfo(dto), OpuslistWithUserInfoVOZH.class);
      }
      // 使用 HashMap 构建返回数据
      HashMap<String, Object> dataMap = new HashMap<>();
      dataMap.put("total", total);
      dataMap.put("data", listVO);

      return AjaxResult.success(dataMap);
    } catch (IllegalArgumentException e) {
      return AjaxResult.error(e.getMessage());
    } catch (Exception e) {
      return AjaxResult.error("作品列表查询失败: " + e.getMessage());
    }
  }

  /**
   * 浏览量加1
   * @param opusId 作品ID
   * @return R<String> 操作结果
   * @see com.dnndo.system.domain.dto.OpusDTO
   */
  @GetMapping("/word/browse/add")
  public R<String> browseAdd(@ApiParam(value = "作品ID", required = true) Long opusId) {
    OpusDTO opusDTO = opusService.selectOpusById(opusId);
    opusDTO.setPageView(opusDTO.getPageView() + 1);
//    opusDTO.setGrade(opusDTO.getGrade() + 0.01);
    int rows = opusService.updateOpusById(opusDTO);
    if (rows <= 0) {
      return R.fail("操作失败");
    }
    return R.ok("操作成功");
  }

  /**
   * 点赞加一
   * @param opusId 作品ID
   * @return R<String> 操作结果
   * @see com.dnndo.system.domain.dto.OpusDTO
   */
  @GetMapping("/work/thumb/add")
  public R<String> thumbAdd(@ApiParam(value = "作品ID", required = true) Long opusId) {
    return opusLikeService.likeOpus(opusId, getUserId());
  }

  /**
   * 首页-文创活动
   * @param language 语言类型（zh/en）
   * @return AjaxResult 包含文创活动信息的响应结果
   * @see com.dnndo.system.domain.dto.OpusDTO
   */
  @Log(title = "首页-文创活动/api/activities?language=zh接口", businessType = BusinessType.INSERT)
  @GetMapping("/activities")
  public AjaxResult selectOpusApi( String language){
    if (language.equals("en"))
      return AjaxResult.success(opusService.selectApiOpusActivitiesEn());
    else
      return AjaxResult.success(opusService.selectApiOpusActivitiesZh());
  }

  /**
   * 新增作品，返回作品id
   * @param dto 前端传入的作品数据传输对象，包含新增字段
   * @return AjaxResult 操作结果返回对象，包含成功或失败状态及作品ID
   * @see com.dnndo.system.domain.dto.OpusDTO
   */
  @Log(title = "作品管理", businessType = BusinessType.INSERT)
  @PostMapping("/insert")
  public AjaxResult insert(@Validated @RequestBody OpusDTO dto) {
    dto.setUserId(getUserId().intValue());
    int opusId = opusService.insertOpus(dto);

    if (opusId > 0) {
      // 获取插入后生成的ID
      int insertedId = dto.getOpusId();
      return AjaxResult.success("新增成功", insertedId);
    } else {
      return AjaxResult.error("新增失败");
    }
  }

  /**
   * 修改作品接口，返回id
   * @param dto 前端传入的作品数据传输对象，包含更新字段
   * @return AjaxResult 操作结果返回对象，包含成功或失败状态及作品ID
   * @see com.dnndo.system.domain.dto.OpusDTO
   */
  @Log(title = "作品管理", businessType = BusinessType.UPDATE)
  @PostMapping("/revise")
  public AjaxResult revise(@Validated @RequestBody OpusDTO dto) {
    OpusDTO opusDTO = BeanDtoVoUtil.convert(dto, OpusDTO.class);
    int updatedId = opusService.updateOpusById(opusDTO);

    if (updatedId > 0) {
      return AjaxResult.success("修改成功", updatedId);
    } else {
      return AjaxResult.error("修改失败");
    }
  }

  /**
   * 校园大使比赛策略-计算并排名作品
   * @param themeId 主题ID
   * @return AjaxResult 操作结果返回对象
   * @see com.dnndo.system.domain.dto.OpusDTO
   */
  @GetMapping("/calculateAndRankOpus")
  public AjaxResult calculateAndRankOpus(Integer themeId) {
    opusService.calculateAndRankOpusByThemeId(themeId);
    return AjaxResult.success("操作成功");
  }

}
